/**
 * Author(s): xuming.Wong <xuming.Wong@gmail.com>
 */

#include "QueryManager.h"
#include "StockInfo.h"
#include "Utilities.h"
#include "HttpDayTransactionQuery.h"
#include "TransactionDatabase.h"

namespace QSThink
{
	
	QueryManager& QueryManager::getSingleton()
	{
		static QueryManager inst;
		return inst;
	}

	QueryManager::QueryManager() :
	_httpQuery(0)
	{
		_httpQuery=new HttpQuery();
		_netAccessMgr=new QNetworkAccessManager(this);
		connect(_netAccessMgr, SIGNAL(finished(QNetworkReply*)), this, SLOT(replyFinished(QNetworkReply*)));

	}

	void QueryManager::getStockInfo(int day,int symbol,QueryListener* receiver )
	{
		LocalQuery localQuery;
		StockDayInfo* dayInfo=localQuery.getStockInfo(day,symbol);


		if(dayInfo){
			std::string name=localQuery.getStockName(symbol);
			float o=dayInfo->openPrice/100.0f;
			float c=dayInfo->closePrice/100.0f;
			float h=dayInfo->highPrice/100.0f;
			float l=dayInfo->lowPrice/100.0f;

			StockInfo info(name,symbol,day,o,c,h,l,
				dayInfo->volume,dayInfo->amount);

			receiver->OnStockInfoReceived(info);
			return;
		}

		_httpQuery->query(day,symbol);

	}

	
	void QueryManager::OnHttpQueryReturn( HttpQuery* query )
	{

	}

	//when delete our created query.
	void QueryManager::OnTransactionsReturn( HttpDayTransactionQuery* query )
	{
		//we should delete the query
		DayTransactionsMap::iterator it=_dayTransactionMap.find(query);
		if(it==_dayTransactionMap.end()){
			return;
		}

		if(!it->second){
			return;
		}


		QueryListener* receiver=it->second;
		if(receiver){
			receiver->OnDayTransactionReceived(query->getDayTransaction());
		}

	}

	void QueryManager::getRealtimeInfo( QString symbol)
	{
		//send http request
		//sh sz
		QString query;
		ExchangeType type=Utilities::getExchangeBySymbol(symbol);
		switch(type){
			case Exchange_ShangHai:
				query="http://hq.sinajs.cn/list=sh";
				query+=symbol;
				break;
			case Exchange_ShenZhen:
				query="http://hq.sinajs.cn/list=sz";
				query+=symbol;
				break;

		}


		QNetworkRequest request;
		request.setUrl(QUrl(query));

		QNetworkReply* reply=_netAccessMgr->get(request);
		connect(reply, SIGNAL(readyRead()), this, SLOT(onReadyRead()));

		//_replyToReceicers.insert(ReplyToReceicerMap::value_type(reply,receiver));

	}

	bool QueryManager::replyFinished( QNetworkReply* reply )
	{
		QString url=reply->url().toString();
		QString symbol=url.right(6);

		QByteArray data = reply->readAll();

		//GB2312's QByteArray Convert to QString Unicode
		//QString ret=QString::fromUtf8(data.data(),data.length());
		QString ret=QTextCodec::codecForName("GB2312")->toUnicode(data);

		//there is A BUG MORE Than one reply?
		if(ret.length()==0){
			return false;//Agly fix
		}

		QString content=ret.split("\"")[1];
		QStringList items=content.split(",");

		int len=items.length();
		if(len!=32){
			return false;
		}

		DiscreteTransaction* info=new DiscreteTransaction;
		QString name=QTextCodec::codecForName("GB2312")->fromUnicode(items[0]).data();
		info->symbol=symbol;
		info->name=items[0];
		info->openPrice=items[1].toFloat();
		info->lastClosePrice=items[2].toFloat();
		info->price=items[3].toFloat();
		info->highPrice=items[4].toFloat();
		info->lowPrice=items[5].toFloat();
		info->buy1=items[6].toFloat();
		info->sell1=items[7].toFloat();
		info->amount=items[8].toInt();
		info->volume=items[9].toInt();

		info->buy1amount=items[10].toFloat();
		info->buy1price=items[11].toFloat();
		info->buy2amount=items[12].toFloat();
		info->buy2price=items[13].toFloat();
		info->buy3amount=items[14].toFloat();
		info->buy3price=items[15].toFloat();
		info->buy4amount=items[16].toFloat();
		info->buy4price=items[17].toFloat();
		info->buy5amount=items[18].toFloat();
		info->buy5price=items[19].toFloat();

		info->sell1amount=items[20].toFloat();
		info->sell1price=items[21].toFloat();
		info->sell2amount=items[22].toFloat();
		info->sell2price=items[23].toFloat();
		info->sell3amount=items[24].toFloat();
		info->sell3price=items[25].toFloat();
		info->sell4amount=items[26].toFloat();
		info->sell4price=items[27].toFloat();
		info->sell5amount=items[28].toFloat();
		info->sell5price=items[29].toFloat();

		info->date=items[30];
		info->time=items[31];

		_transactions.push_back(info);

		persist();


		int cnt=_listeners.size();
		for(int i=0;i<cnt;++i){
			_listeners[i]->OnTransactionReceived(info);
		}

		return true;
	}

	bool QueryManager::onReadyRead()
	{
		return true;

	}

	void QueryManager::persist()
	{
		
	}

	void QueryManager::addListener( QueryListener* listener )
	{
		_listeners.push_back(listener);
	}



	QueryListener::QueryListener()
	{
		QueryManager::getSingleton().addListener(this);
	}

}

